#include "Shield.h"
#include "Game.h"
#include "StringLib.h"
#include "Renderer.h"
#include "Util.h"

Shield::Shield(ShieldType type, MaterialType materialType, ShieldPrefix prefix, ShieldSuffix suffix, bool highQuality) : EquippableItem(GT_IT_SHIELD) {
	m_types[TH_SHIELD_TYPE] = type;
	m_materialType = materialType;
	m_prefix = prefix;
	m_suffix = suffix;
	m_highQuality = highQuality;
	const ShieldInfo& info = g_objectDatabase->getShieldInfo(type);
	calculateStats(info);
}

Shield::Shield(std::ifstream& file) : EquippableItem(GT_IT_SHIELD, file) {
	int* tokens = Util::intSplit(file);
	m_types[TH_SHIELD_TYPE] = tokens[0];
	m_prefix = ShieldPrefix(tokens[1]);
	m_suffix = ShieldSuffix(tokens[2]);
	m_materialType = MaterialType(tokens[3]);
	m_highQuality = tokens[4] == 1;
	const ShieldInfo& info = g_objectDatabase->getShieldInfo(ShieldType(tokens[0]));
	calculateStats(info);
	m_block = tokens[5];
	delete[] tokens;
}

Shield::~Shield() {
}

void Shield::calculateStats(const ShieldInfo& info) {
	m_defaultBlock = info.block;
	m_weight = info.weight;
	switch(m_materialType) {
	case MT_OAK:
		m_defaultBlock -= m_defaultBlock / 20;
		m_weight -= m_weight / 20;
		break;
	case MT_WALNUT:
		m_defaultBlock -= m_defaultBlock / 20;
		m_weight -= m_weight / 10;
		break;
	case MT_COPPER:
		break;
	case MT_IRON:
		m_defaultBlock -= m_defaultBlock / 5;
		m_weight += m_weight / 10;
		break;
	case MT_BRONZE:
		m_defaultBlock += m_defaultBlock / 5;
		break;
	case MT_BRASS:
		m_defaultBlock += m_defaultBlock / 5;
		break;
	}

	m_block = m_defaultBlock;

	if(m_highQuality) {
		m_block += 5;
		m_weight -= m_weight / 10;
	}
}

void Shield::save(std::ofstream& file) const {
	file << getType(TH_GENERIC_TYPE) << "\n";
	EquippableItem::save(file);
	file << getType(TH_SHIELD_TYPE) << " " << m_prefix << " " << m_suffix << " " << m_materialType << " " << (m_highQuality ? 1 : 0) << " " << m_block << "\n";
}

void Shield::render(float x, float y) {
	g_renderer->render(*this, x, y);
}

std::string Shield::getItemName(int mod) const {
	std::string output = "";
	if(m_statusIdentified)
		output += g_stringLib->getMiscString(MST_STATUS, m_status) + " ";

	if(m_equippableIdentified) {
		if(m_highQuality)
			output += "high quality ";
		if(m_prefix != SP_NONE)
			output += g_stringLib->getMiscString(MST_SHIELD_PREFIX, m_prefix) + " ";
	} else {
		if(isEnchanted())
			output += "enchanted ";
	}
	output += g_stringLib->getMiscString(MST_MATERIAL, m_materialType) + " " + getBasicName();
	if(m_equippableIdentified && m_suffix)
		output += " " + g_stringLib->getMiscString(MST_SHIELD_SUFFIX, m_suffix);
	if(m_equippableIdentified)
		output += " (" + Util::intToString(m_block) + ")";
	else
		output += " (" + Util::intToString(m_defaultBlock) + ")";
	return output;
}

bool Shield::isEnchanted() const {
	return m_prefix != SP_NONE || m_suffix != SS_OF_NONE || m_highQuality;
}


void Shield::logDetails(TextLog& log) const {
	Item::logDetails(log);
	log.addBlankLine();
	log.addLine(g_stringLib->getTextString(ST_SHIELD_BLOCK, (m_equippableIdentified ? Util::intToString(m_block).c_str() : Util::intToString(m_defaultBlock)).c_str()));
	log.addBlankLine();
	log.addLine(g_stringLib->getTextString(ST_SHIELD_MATERIAL, g_stringLib->getMiscString(MST_MATERIAL, m_materialType).c_str()));
	if(m_equippableIdentified) {
		if(m_highQuality)
			log.addLine(g_stringLib->getTextString(ST_WEAPON_HIGH_QUALITY));
		if(m_prefix != SP_NONE)
			log.addLine(g_stringLib->getMiscString(MST_SHIELD_PREFIX, m_prefix));
		if(m_suffix != SS_OF_NONE)
			log.addLine(g_stringLib->getMiscString(MST_SHIELD_SUFFIX, m_suffix));
	}
}
